import { config } from '@/config/config'
import store from '@/store'
import { uploadFile } from '@/api/common'

// 上传错误信息
const uploadError = (uploadData, uploadPath) => {
  try {
    if (
      typeof uploadData != 'object' ||
      !uploadPath ||
      (uploadData.detail &&
        (uploadData.detail.message === 'Network Error' ||
          uploadData.detail.message === 'Request failed with status code 503'))
    )
      return

    const jsonString = JSON.stringify(uploadData, null, 4) // 将uploadData转换为json字符串，第三个参数是确定缩进的距离
    const blob = new Blob([jsonString], { type: 'application/json' }) // 创建一个新的 Blob 对象
    // 生成文件
    const format = uploadData.format ? uploadData.format : 'json' // 文件格式
    const date = uploadData.date ? uploadData.date : Date.now() // 文件日期
    const file = new File([blob], `${Date.now()}.${format}`, {
      type: format,
      lastModified: date
    })
    // 开始上传
    const formData = new FormData()
    formData.append('file', file, `${date}.${format}`)
    formData.append('path', uploadPath)
    uploadFile(formData)
      .then(() => {})
      .catch(() => {}) // 捕获错误，防止重复请求
  } catch (error) {}
}

const install = (Vue) => {
  // Promise UnhandledRejection
  window.addEventListener('unhandledrejection', function (e) {
    try {
      e.preventDefault()
      // 阻止异常向上抛出
      const {
        reason: { message, stack }
      } = e

      const { tenantId, serialNo, userId } = store.state.user
      const format = 'json'
      const date = Date.now()
      const uploadData = {
        type: 'Promise UnhandledRejection',
        version: config.version,
        baseUrl: config.baseUrl,
        format,
        schoolId: tenantId,
        userId,
        serialNo,
        date,
        detail: {
          message,
          stack
        }
      }
      const uploadPath = `devicelog/${tenantId}/${serialNo}/${userId}/${date}.${format}`
      uploadError(uploadData, uploadPath)
    } catch (error) {}
  })

  // Vue ErrorHandler
  Vue.config.errorHandler = function (err, vm, info) {
    try {
      // vm 为抛出异常的 Vue 实例  info 为 Vue 特定的错误信息，比如错误所在的生命周期钩子
      const {
        message, // 异常信息
        stack // 异常堆栈信息
      } = err

      const { tenantId, serialNo, userId } = store.state.user
      const format = 'json'
      const date = Date.now()
      const uploadData = {
        type: 'Vue ErrorHandler',
        version: config.version,
        baseUrl: config.baseUrl,
        format,
        schoolId: tenantId,
        userId,
        serialNo,
        date,
        detail: {
          message,
          stack
        }
      }
      const uploadPath = `devicelog/${tenantId}/${serialNo}/${userId}/${date}.${format}`
      uploadError(uploadData, uploadPath)
    } catch (error) {}
  }
}

export default {
  install
}
